package com.itlong.cloud.controller.project;

import com.alibaba.fastjson.JSONObject;
import com.itlong.cloud.POJO.DTO.operate.*;
import com.itlong.cloud.POJO.VO.MessageVO;
import com.itlong.cloud.POJO.VO.operate.OperatePropertyAccountDetailVO;
import com.itlong.cloud.POJO.VO.operate.OperatePropertyAccountVO;
import com.itlong.cloud.POJO.VO.operate.OperatePropertyDeveloperVO;
import com.itlong.cloud.POJO.VO.property.PropertyFunctionVO;
import com.itlong.cloud.abstracts.BaseController;
import com.itlong.cloud.annotation.AuthAccessRequired;
import com.itlong.cloud.annotation.LoggerInfo;
import com.itlong.cloud.annotation.UnAuthAccessRequired;
import com.itlong.cloud.annotation.UnParamEncrypt;
import com.itlong.cloud.constants.LogDescConstant;
import com.itlong.cloud.enumerate.DataStatusEnum;
import com.itlong.cloud.enumerate.PropertyPublicRoleEnum;
import com.itlong.cloud.enumerate.ecode.BaseErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.OperateErrorCodeEnum;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.user.operate.IOperatePropertyAccountServiceClient;
import com.itlong.cloud.user.property.IPropertyFunctionServiceClient;
import com.itlong.cloud.utils.network.http.HttpProtocolUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <desc>
 * 运营-物业账号控制器
 * </desc>
 *
 * @createDate 2017-10-25.
 */
@RestController
@RequestMapping("/project/propertyUser")
public class OperatePropertyAccountController extends BaseController {
    private final static Logger LOG = LoggerFactory.getLogger(OperatePropertyAccountController.class);

    @Autowired
    IOperatePropertyAccountServiceClient iOperatePropertyAccountServiceClient;
    @Autowired
    IPropertyFunctionServiceClient iPropertyFunctionServiceClient;

    /**
     * <desc>
     * 添加新的物业账号
     * <desc/>
     *
     * @param saveDTO 新增账号信息
     * @return
     * @author Chunjian.G
     * @createDate 2017-10-27
     */
    @AuthAccessRequired
    @LoggerInfo(operateDesc = LogDescConstant.PROPERTY_ACCOUNT_SAVE_LOG_DESC)
    @RequestMapping(value = "/add", method = RequestMethod.POST)
    @ResponseBody
    public Object savePropertyAccount(OperatePropertyAccountSaveDTO saveDTO) {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            saveDTO = HttpProtocolUtil.parseRequestParamToDTO(OperatePropertyAccountSaveDTO.class, request);
            //合法性判断
            if (null == saveDTO) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            if (saveDTO.getRobotSwitch() != null && saveDTO.getRobotSwitch() == 1 && (saveDTO.getDockMode() == null || saveDTO.getLoginCount() == null
                    || StringUtils.isBlank(saveDTO.getEffectStartTime()) || StringUtils.isBlank(saveDTO.getEffectEndTime()))) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            //物业名称
            if (StringUtils.isBlank(saveDTO.getPropertyName()) || saveDTO.getPropertyName().length() > 50) {
                return new MessageVO(OperateErrorCodeEnum.PROPERTY_ACCOUNT_PROPERTY_NAME_INVALID_ERR.getErrorCode());
            }
            //管辖项目
            if (StringUtils.isBlank(saveDTO.getProjectIds())) {
                return new MessageVO(OperateErrorCodeEnum.PROPERTY_ACCOUNT_MANAGE_PROJECT_INVALID_ERR.getErrorCode());
            }
            //备注
            if (null != saveDTO.getDescription() && saveDTO.getDescription().length() > 255) {
                return new MessageVO(OperateErrorCodeEnum.PROPERTY_ACCOUNT_DESCRIPTION_TOO_LONG_ERR.getErrorCode());
            }
            //状态值 1.正常 2.禁用
            if (null != saveDTO.getStatus() && (saveDTO.getStatus() != DataStatusEnum.NORMAL.getType()
                    && saveDTO.getStatus() != DataStatusEnum.BAN.getType())) {
                return new MessageVO(OperateErrorCodeEnum.PROPERTY_ACCOUNT_STATUS_INVALID_ERR.getErrorCode());
            }
            //管理员类型
            if (StringUtils.isBlank(saveDTO.getRoleId())
                    || !PropertyPublicRoleEnum.containsRoleId(saveDTO.getRoleId())) {
                return new MessageVO(OperateErrorCodeEnum.PROPERTY_ACCOUNT_ROLE_ROLE_ID_INVALID_ERR.getErrorCode());
            }
            //账号名(合法性及存在性)
            if (StringUtils.isBlank(saveDTO.getUserName()) || !saveDTO.getUserName().matches("[a-zA-Z][a-zA-Z0-9_@-]{4,29}")) {
                return new MessageVO(OperateErrorCodeEnum.PROPERTY_ACCOUNT_USER_NAME_INVALID_ERR.getErrorCode());
            } else if (iOperatePropertyAccountServiceClient.checkPropertyAccountExist(saveDTO.getUserName()) > 0) {

                return new MessageVO(OperateErrorCodeEnum.PROPERTY_ACCOUNT_USER_NAME_EXIST_ERR.getErrorCode());
            }
            ////取消 一对一，修改为一个项目对多个开发者
            //检测某项目某角色用户是否已存在（每个项目的每个公共角色，只能有一个用户）
        /*    String[] projIds = StringHandlerUtil.splitString(saveDTO.getProjectIds());
            for (String projId : projIds){
                if (iOperatePropertyAccountServiceClient.checkProjectRoleExist(projId, saveDTO.getRoleId(), null) > 0 &&
                        !saveDTO.getRoleId().equals(PropertyPublicRoleEnum.DEVELOPER.getRoleId())){
                    return new MessageVO(BaseErrorCodeEnum.ERROR.getErrorCode(),
                            String.format("项目【%s】角色【%s】已存在用户", projId,
                                    PropertyPublicRoleEnum.getRoleNameByRoleId(saveDTO.getRoleId())));
                }
            }*/
            //取消 一对一，修改为一个项目对多个开发者
           /* if ("6".equals(saveDTO.getRoleId()) && saveDTO.getProjectIds().contains(",")) {
                return new MessageVO(BaseErrorCodeEnum.ERROR.getErrorCode(), "一卡通开发者只能绑定一个项目");
            }*/

            Integer res = iOperatePropertyAccountServiceClient.savePropertyAccount(saveDTO);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), res);

        } catch (Exception e) {
            throw new DataAccessException("【运营_物业账号管理_物业账号savePropertyAccount】添加物业账号失败", e);
        }
    }


    /**
     * <desc>
     * 更新单个物业账号
     * <desc/>
     *
     * @param updateDTO 账号更新信息
     * @return
     * @author Chunjian.G
     * @createDate 2017-10-27
     */
    @AuthAccessRequired
    @LoggerInfo(operateDesc = LogDescConstant.PROPERTY_ACCOUNT_UPDATE_LOG_DESC)
    @RequestMapping(value = "/update", method = RequestMethod.POST)
    @ResponseBody
    public Object updatePropertyAccount(OperatePropertyAccountUpdateDTO updateDTO) {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            updateDTO = HttpProtocolUtil.parseRequestParamToDTO(OperatePropertyAccountUpdateDTO.class, request);
            if (null == updateDTO) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }
            //用户id
            if (StringUtils.isBlank(updateDTO.getUserId())) {
                return new MessageVO(OperateErrorCodeEnum.USER_ID_EMPTY_ERR.getErrorCode());
            }
            //状态值 1.正常 2.禁用
            if (null != updateDTO.getStatus() && (updateDTO.getStatus() != DataStatusEnum.NORMAL.getType()
                    && updateDTO.getStatus() != DataStatusEnum.BAN.getType())) {
                return new MessageVO(OperateErrorCodeEnum.PROPERTY_ACCOUNT_STATUS_INVALID_ERR.getErrorCode());
            }
            //备注
            if (null != updateDTO.getDescription() && updateDTO.getDescription().length() > 255) {
                return new MessageVO(OperateErrorCodeEnum.PROPERTY_ACCOUNT_DESCRIPTION_TOO_LONG_ERR.getErrorCode());
            }

            //获取账号旧数据
            OperatePropertyAccountDetailVO detailVO = iOperatePropertyAccountServiceClient.getDetail(updateDTO.getUserId());
            updateDTO.setRoleId(detailVO.getRoleId());
            updateDTO.setOldManageProjectIds(detailVO.getProjectIds());

            //管辖项目
            if (StringUtils.isNotBlank(updateDTO.getProjectIds())) {
             /*   //检测某项目某角色用户是否已存在（每个项目的每个公共角色，只能有一个用户）
                String[] projIds = StringHandlerUtil.splitString(updateDTO.getProjectIds());
                for (String projId : projIds){
                    if (iOperatePropertyAccountServiceClient.checkProjectRoleExist(projId, null, updateDTO.getUserId()) > 0){
                        return new MessageVO(BaseErrorCodeEnum.ERROR.getErrorCode(),
                                String.format("项目【%s】已存在该角色用户", projId));
                    }
                }*/

                String[] oldProjs = StringHandlerUtil.splitString(updateDTO.getOldManageProjectIds());
                if (oldProjs.length > 0 && StringUtils.isBlank(updateDTO.getFunctionIds())) {
                    List<String> oldFuncIds = iPropertyFunctionServiceClient.getFunctionIdsByRoleProject(updateDTO.getRoleId(), oldProjs[0]);
                    updateDTO.setFunctionIds(StringUtils.join(oldFuncIds, ','));
                }
                //取消一对一  一个项目对多个开发者
               /* if ("6".equals(updateDTO.getRoleId()) && updateDTO.getProjectIds().contains(",")) {
                    return new MessageVO(BaseErrorCodeEnum.ERROR.getErrorCode(), "一卡通开发者只能绑定一个项目");
                }*/
            }

            Integer res = iOperatePropertyAccountServiceClient.updatePropertyAccount(updateDTO);
            return new MessageVO(updateDTO.getUserId(), BaseErrorCodeEnum.SUCCESS.getErrorCode(), res);
        } catch (Exception e) {
            throw new DataAccessException("【运营_物业账号管理_物业账号updatePropertyAccount】更新物业账号失败", e);
        }
    }

    /**
     * <desc>
     * 分页获取物业账号简易信息列表
     * <desc/>
     *
     * @param pageDTO 查询参数
     * @return
     * @author Chunjian.G
     * @createDate 2017-10-27
     */
    @AuthAccessRequired
    @RequestMapping(value = "/getPage", method = RequestMethod.POST)
    @ResponseBody
    public Object getPage(OperatePropertyAccountGetPageDTO pageDTO) {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            pageDTO = HttpProtocolUtil.parseRequestParamToDTO(OperatePropertyAccountGetPageDTO.class, request);
            Page<OperatePropertyAccountVO> page = iOperatePropertyAccountServiceClient.getPage(pageDTO);
            MessageVO messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), page);
            return messageVO;
        } catch (Exception e) {
            throw new DataAccessException("【运营_物业账号管理_物业账号getPage】查询物业账号失败", e);
        }
    }

    /**
     * <desc>
     * 获取单个物业账号详情
     * <desc/>
     *
     * @param userId 用户id
     * @return
     * @author Chunjian.G
     * @createDate 2017-10-27
     */
    @AuthAccessRequired
    @RequestMapping(value = "/getDetail", method = RequestMethod.POST)
    @ResponseBody
    public Object getDetail(String userId) {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            userId = request.getAttribute("userId") == null ? null : request.getAttribute("userId").toString();
            if (StringUtils.isBlank(userId)) {
                return new MessageVO(OperateErrorCodeEnum.USER_ID_EMPTY_ERR.getErrorCode());
            }
            OperatePropertyAccountDetailVO detailVO = iOperatePropertyAccountServiceClient.getDetail(userId);
            if (null != detailVO && !StringUtils.isBlank(detailVO.getRoleId())) {
                String[] projIds = StringHandlerUtil.splitString(detailVO.getProjectIds());
                if (projIds.length > 0) {
                    List<PropertyFunctionVO> functions =
                            iPropertyFunctionServiceClient.getAllotFunction(detailVO.getRoleId(), projIds[0]);
                    detailVO.setFunctions(functions);
                } else {
                    List<PropertyFunctionVO> functions =
                            iPropertyFunctionServiceClient.getAllotFunction("", "");
                    detailVO.setFunctions(functions);
                }

                String[] projNames = StringHandlerUtil.splitString(detailVO.getProjectNames());
                List<OperatePropertyAccountDetailVO.SimpleProject> projects = new ArrayList<>();
                for (int i = 0; i < projIds.length; i++) {
                    OperatePropertyAccountDetailVO.SimpleProject project = new OperatePropertyAccountDetailVO.SimpleProject();
                    project.setProjectId(projIds[i]);
                    if (i < projNames.length) {
                        project.setProjectName(projNames[i]);
                    }
                    projects.add(project);
                }
                detailVO.setProjectInfos(projects);
            }
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), detailVO);
        } catch (Exception e) {
            throw new DataAccessException("【运营_物业账号管理_物业账号getDetail】查询物业账号详情失败", e);
        }
    }

    /**
     * <desc>
     *      批量删除物业账号
     * <desc/>
     *
     * @param userIds 物业账号id，多个以英文逗号分隔
     * @return
     * @author Chunjian.G
     * @createDate 2017-10-27
     */
//    @LoggerInfo(operateDesc = LogDescConstant.PROPERTY_ACCOUNT_DEL_LOG_DESC)
//    @RequestMapping(value = "/del", method = RequestMethod.POST)
//    @ResponseBody
//    public MessageVO removePropertyAccounts(String userIds){
//        try {
//            if (StringUtils.isBlank(userIds)){
//                return new MessageVO(OperateErrorCodeEnum.USER_ID_EMPTY_ERR.getErrorCode());
//            }
//
//            Integer res = iOperatePropertyAccountServiceClient.removePropertyAccounts(userIds);
//            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), res);
//        }catch (Exception e){
//            throw new DataAccessException("【运营_物业账号管理_物业账号del】删除物业账号失败", e);
//        }
//    }

    /**
     * <desc>
     * 批量重置物业账号密码
     * <desc/>
     *
     * @param userIds 物业账号id，多个以英文逗号分隔
     * @return
     * @author Chunjian.G
     * @createDate 2017-10-27
     */
    @AuthAccessRequired
    @LoggerInfo(operateDesc = LogDescConstant.USER_PROPERTY_RESETPASSWORD_LOG_DESC)
    @RequestMapping(value = "/resetPwd", method = RequestMethod.POST)
    @ResponseBody
    public Object resetPwd(String userIds) {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            userIds = request.getAttribute("userIds") == null ? null : request.getAttribute("userIds").toString();
            if (StringUtils.isBlank(userIds)) {
                return new MessageVO(OperateErrorCodeEnum.USER_ID_EMPTY_ERR.getErrorCode());
            }

            Integer res = iOperatePropertyAccountServiceClient.resetPassword(userIds);
            return new MessageVO(userIds, BaseErrorCodeEnum.SUCCESS.getErrorCode(), res);
        } catch (Exception e) {
            throw new DataAccessException("【运营_物业账号管理_物业账号resetPwd】物业账号密码重置失败", e);
        }
    }

    /**
     * <desc>
     * 分页获取物业开发者账号信息
     * <desc/>
     *
     * @param pageDTO 查询参数
     * @return
     * @author Qiang.S
     * @createDate 2018-06-29
     */
    @AuthAccessRequired
    @RequestMapping(value = "/getDeveloperPage", method = RequestMethod.POST)
    @ResponseBody
    public Object getDeveloperPage(OperatePropertyDeveloperGetPageDTO pageDTO) {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            pageDTO = HttpProtocolUtil.parseRequestParamToDTO(OperatePropertyDeveloperGetPageDTO.class, request);
            Page<OperatePropertyDeveloperVO> page = iOperatePropertyAccountServiceClient.getDeveloperPage(pageDTO);
            MessageVO messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), page);
            return messageVO;
        } catch (Exception e) {
            throw new DataAccessException("【运营_物业账号管理_分页获取物业开发者账号信息getDeveloperPage】分页获取物业开发者账号信息失败", e);
        }
    }

    /**
     * <desc>
     * 删除开发者账号信息
     * <desc/>
     *
     * @param userId 用户编号
     * @return
     * @author Qiang.S
     * @createDate 2018-09-05
     */
    @AuthAccessRequired
    @LoggerInfo(operateDesc = LogDescConstant.DELETE_DEVELOPEROG_INFO_LOG_DESC)
    @RequestMapping(value = "/deleteDevelopInfo", method = RequestMethod.POST)
    @ResponseBody
    public Object deleteDeveloperInfo(String userId, String projectId) {
        MessageVO messageVO;
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            userId = request.getAttribute("userId") == null ? null : request.getAttribute("userId").toString();
            projectId = request.getAttribute("projectId") == null ? null : request.getAttribute("projectId").toString();
            if (StringUtils.isBlank(userId)) {
                return new MessageVO(OperateErrorCodeEnum.USER_ID_EMPTY_ERR.getErrorCode());
            }
            if (StringUtils.isBlank(projectId)) {
                return new MessageVO(OperateErrorCodeEnum.PUB_PROJECT_ID_EMPTY_ERR.getErrorCode());
            }
            iOperatePropertyAccountServiceClient.removePropertyDeveloper(userId, projectId);
            messageVO = new MessageVO(userId, BaseErrorCodeEnum.SUCCESS.getErrorCode());
            return messageVO;
        } catch (Exception e) {
            throw new DataAccessException("【运营_物业账号管理_删除开发者账号信息deleteDeveloperInfo】删除开发者账号信息失败", e);
        }
    }

    /**
     * <desc>
     * <p>
     * </desc>
     *
     * @param
     * @return
     * @Author Zhu.yj
     * @createDate 2020/8/28
     */
    @PostMapping("testNullException")
    public Object testNullException() {
        try {
            JSONObject json = (JSONObject) JSONObject.parse(null);
            if (json.get("code").toString().equals("0")) {
                JSONObject data = (JSONObject) JSONObject.parse(json.get("data").toString());
//            projectId = data.get("projectId").toString();
                return new MessageVO(BaseErrorCodeEnum.ERROR.getErrorCode(), 0);
            }
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), 1);
        } catch (Exception e) {
            throw new DataAccessException("错误", e);
        }
    }

    @RequestMapping(value = "chckPropertyAccountExist", method = RequestMethod.POST)
    @ResponseBody
    public Object getChckPropertyAccountExist(OperatePropertyAccountSaveDTO saveDTO) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        saveDTO = HttpProtocolUtil.parseRequestParamToDTO(OperatePropertyAccountSaveDTO.class, request);
        //合法性判断
        if (null == saveDTO) {
            return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
        }

        try {
            Map<String, String> map = new HashMap<>();

            int flag = 0;
            String userName = saveDTO.getUserName();
            Integer exist = iOperatePropertyAccountServiceClient.checkPropertyAccountExist(userName);
            if (exist > 0) {
                while (flag == 0) {
                    int a = (int) (Math.random() * 2) + 3;
                    char str = ' ';
                    if (a == 3) {
                        str = 'a';
                    } else if (a == 4) {
                        str = 'A';
                    }
                    str = (char) (str + (Math.random() * 26));
                    userName = saveDTO.getUserName().substring(0, 3) + str + saveDTO.getUserName().substring(3, saveDTO.getUserName().length());
                    Integer inta = iOperatePropertyAccountServiceClient.checkPropertyAccountExist(userName);
                    if (inta == 0) {
                        flag = 1;
                        map.put("userName", userName);
                    } else {
                        flag = 0;
                    }
                }
                return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), map);
            } else {
                map.put("userName", saveDTO.getUserName());
                return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), map);
            }
        } catch (Exception e) {
            throw new DataAccessException("【运营_物业账号管理_物业账号getChckPropertyAccountExist】检测物业账号是否重复失败", e);
        }

    }

    /**
     * <desc>
     *      处理集团物业管理员旧数据
     * </desc>
     *
     * @param
     * @return
     * @Author Zhu.yj
     * @createDate  2021/5/21
     */
    @UnAuthAccessRequired
    @UnParamEncrypt
    @PostMapping("/handlerGroupAdminFunction")
    public Object handlerGroupAdminFunction(){
        try {
            Integer result = iOperatePropertyAccountServiceClient.handlerGroupAdminFunction();
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), result);
        }catch (Exception e){
            throw new DataAccessException("【处理集团物业管理员】处理集团物业管理员旧数据失败", e);
        }
    }

}
